package org.oimwrapper.connectors.internal;

import org.oimwrapper.connectors.*;

import Thor.API.Base.*;
import Thor.API.Operations.*;
import Thor.API.tcUtilityFactory;
import com.thortech.util.logging.*;
import com.thortech.xl.dataaccess.*;

/**
 * Creates instances of the internal utility classes.
 * 
 * THIS IS AN INTERNAL CLASS AND SHOULD NOT BE USED DIRECTLY.
 */
public class OIMUtilityGetter {
	
	/**
	 * The calling task.
	 */
	private OIMTaskBase task;
	
	/**
	 * The calling adapter;
	 */
	private OIMAdapterBase adapter;
	
	/**
	 * The logger to use.
	 */
	private Logger logger;
	
	/**
	 * The database reference to use.
	 */
	private tcDataProvider database;
	
	/**
	 * The lookup operations.
	 */
	private tcLookupOperationsIntf lookupOp;
	
	/**
	 * The property operations.
	 */
	private tcPropertyOperationsIntf propertyOp;
	
	/**
	 * The help operations.
	 */
	private tcHelpOperationsIntf helpOp;
	
	/**
	 * The IT Resource definition operations.
	 */
	private tcITResourceDefinitionOperationsIntf itResDefOp;
	
	/**
	 * The IT resource instance operations.
	 */
	private tcITResourceInstanceOperationsIntf itResInstOp;
	
	/**
	 * The organization operations.
	 */
	private tcOrganizationOperationsIntf orgOp;
	
	/**
	 * The resource object operations.
	 */
	private tcObjectOperationsIntf objectOp;
	
	/**
	 * The user operations.
	 */
	private tcUserOperationsIntf userOp;
	
	/**
	 * The password operations.
	 */
	private tcPasswordOperationsIntf passwordOp;
	
	/**
	 * The group operations.
	 */
	private tcGroupOperationsIntf groupOp;
	
	/**
	 * The form definition operations.
	 */
	private tcFormDefinitionOperationsIntf formDefOp;
	
	/**
	 * The form instance operations.
	 */
	private tcFormInstanceOperationsIntf formInstOp;
	
	/**
	 * The email operations.
	 */
	private tcEmailOperationsIntf emailOp;
	
	/**
	 * The access policy operations.
	 */
	private tcAccessPolicyOperationsIntf policyOp;
	
	/**
	 * The reconciliation operations.
	 */
	private tcReconciliationOperationsIntf reconOp;
	
	/**
	 * The request operations.
	 */
	private tcRequestOperationsIntf requestOp;

	/**
	 * Constrcutor for use from {@link OIMTaskBase};
	 * 
	 * @param Task The calling task.
	 * @param Database The database reference to use.
	 * @exception Exception
	 */
	public OIMUtilityGetter(OIMTaskBase Task, tcDataProvider Database) throws Exception {
		task = Task;
		adapter = null;
		database = Database;
		logger = getLogger();
		loadUtils();
	}
	
	/**
	 * Constrcutor for use from {@link OIMAdapterBase};
	 * 
	 * @param Adapter The calling adapter.
	 * @param Database The database reference to use.
	 * @exception Exception
	 */
	public OIMUtilityGetter(OIMAdapterBase Adapter, tcDataProvider Database) throws Exception {
		task = null;
		adapter = Adapter;
		database = Database;
		logger = getLogger();
		loadUtils();
	}
        
        /**
	 * Constrcutor for use from {@link OIMAdapterBase};
	 * 
	 * @param Database The database reference to use.
	 * @exception Exception
	 */
	public OIMUtilityGetter(tcDataProvider Database) throws Exception {
		task = null;
		adapter = null;
		database = Database;
		logger = getLogger();
		loadUtils();
	}
	
	/**
	 * Wrapper to OIM api utility classes.
	 * 
	 * @param UtilityClass The class of the utility to get.
	 * @return The utility object.
	 * @exception Exception
	 */
	private tcUtilityOperationsIntf getUtility(Class UtilityClass) throws Exception {
		if (task != null) {
			return task.getUtility(UtilityClass);
		} else if (adapter != null) {
			return adapter.getUtility(UtilityClass);
		} else if (database != null) {
                    return tcUtilityFactory.getUtility(database, UtilityClass.getName());
                    
                } else {
			return null;
		}
	}
	
	/**
	 * Wrapper to get logger instance.
	 * 
	 * @return The logger instance.
	 */
	private Logger getLogger() {
		if (task != null) {
			return task.logger;
		} else if (adapter != null) {
			return adapter.logger;
		} else {
			return null;
		}
	}
	
	/**
	 * Internal function to load all the utility objects.
	 * 
	 * @exception Exception
	 */
	private void loadUtils() throws Exception {
		StackTraceElement[] elements = (new Throwable()).getStackTrace();
		if (elements.length > 2) {
			String caller = elements[2].getClassName();
			if (!caller.equals(OIMTaskBase.class.getName()) && !caller.equals(OIMAdapterBase.class.getName())) {
				throw new RuntimeException("These utility functions are internal and should not be accessed directly.");
			}
		}
		lookupOp = (tcLookupOperationsIntf) getUtility(tcLookupOperationsIntf.class);
		propertyOp = (tcPropertyOperationsIntf) getUtility(tcPropertyOperationsIntf.class);
		helpOp = (tcHelpOperationsIntf) getUtility(tcHelpOperationsIntf.class);
		itResDefOp = (tcITResourceDefinitionOperationsIntf) getUtility(tcITResourceDefinitionOperationsIntf.class);
		itResInstOp = (tcITResourceInstanceOperationsIntf) getUtility(tcITResourceInstanceOperationsIntf.class);
		orgOp = (tcOrganizationOperationsIntf) getUtility(tcOrganizationOperationsIntf.class);
		objectOp = (tcObjectOperationsIntf) getUtility(tcObjectOperationsIntf.class);
		userOp = (tcUserOperationsIntf) getUtility(tcUserOperationsIntf.class);
		passwordOp = (tcPasswordOperationsIntf) getUtility(tcPasswordOperationsIntf.class);
		groupOp = (tcGroupOperationsIntf) getUtility(tcGroupOperationsIntf.class);
		formDefOp = (tcFormDefinitionOperationsIntf) getUtility(tcFormDefinitionOperationsIntf.class);
		formInstOp = (tcFormInstanceOperationsIntf) getUtility(tcFormInstanceOperationsIntf.class);
		emailOp = (tcEmailOperationsIntf) getUtility(tcEmailOperationsIntf.class);
		policyOp = (tcAccessPolicyOperationsIntf) getUtility(tcAccessPolicyOperationsIntf.class);
		reconOp = (tcReconciliationOperationsIntf) getUtility(tcReconciliationOperationsIntf.class);
		requestOp = (tcRequestOperationsIntf) getUtility(tcRequestOperationsIntf.class);
	}
	
	/**
	 * Gets the policy utilities.
	 * 
	 * @return The policy utilities.
	 */
	public OIMAccessPolicyUtilities getPolicyUtils() {
		return new OIMAccessPolicyUtilities(logger, policyOp, formDefOp, formInstOp, objectOp, groupOp);
	}
	
	/**
	 * Gets the database utilities.
	 * 
	 * @return The database utilities.
	 */
	public OIMDatabaseUtilities getDatabaseUtils() {
		return new OIMDatabaseUtilities(logger, database);
	}
	
	/**
	 * Gets the email utilities.
	 * 
	 * @return The email utilities.
	 */
	public OIMEmailUtilities getEmailUtils() {
		return new OIMEmailUtilities(logger, emailOp, propertyOp, database);
	}
	
	/**
	 * Gets the form utilities.
	 * 
	 * @return The form utilities.
	 */
	public OIMFormUtilities getFormUtilities() {
		return new OIMFormUtilities(logger, formDefOp, formInstOp);
	}
        
        /**
	 * Gets the form utilities.
	 * 
	 * @return The form utilities.
	 */
	public static OIMFormUtilities getFormUtilities(Logger ClassLogger, tcFormDefinitionOperationsIntf FormDefOp, tcFormInstanceOperationsIntf FormInstOp) {
		return new OIMFormUtilities(ClassLogger, FormDefOp, FormInstOp);
	}
        
        /**
	 * Gets the form utilities.
	 * 
	 * @return The form utilities.
	 */
	public OIMObjectFormUtilities getObjectFormUtilities() {
		return new OIMObjectFormUtilities(logger, objectOp,formInstOp, formDefOp);
	}
        
        /**
	 * Gets the form utilities.
	 * 
	 * @return The form utilities.
	 */
	public static OIMObjectFormUtilities getObjectFormUtilities(Logger ClassLogger, tcObjectOperationsIntf ObjectOp, tcFormInstanceOperationsIntf FormInstOp, tcFormDefinitionOperationsIntf FormDefOp) {
		return new OIMObjectFormUtilities(ClassLogger, ObjectOp,FormInstOp, FormDefOp);
	}
	
	/**
	 * Gets the group utilities.
	 * 
	 * @return The group utilities.
	 */
	public OIMGroupUtilities getGroupUtils() {
		return new OIMGroupUtilities(logger, groupOp, database, new OIMStandardUtilities(logger, propertyOp, helpOp));
	}
	
	/**
	 * Gets the IT resource utilities.
	 * 
	 * @return The IT resource utilities.
	 */
	public OIMITResourceUtilities getItResUtils() {
		return new OIMITResourceUtilities(logger, itResDefOp, itResInstOp, new OIMStandardUtilities(logger, propertyOp, helpOp));
	}
        
        /**
	 * Gets the IT resource utilities.
	 * 
	 * @return The IT resource utilities.
	 */
	public static OIMITResourceUtilities getItResUtils(Logger ClassLogger, tcITResourceDefinitionOperationsIntf ItResDefOp, tcITResourceInstanceOperationsIntf ItResInstOp) {
		return new OIMITResourceUtilities(ClassLogger, ItResDefOp, ItResInstOp);
	}
	
	/**
	 * Gets the lookup utilities.
	 * 
	 * @return The lookup utilities.
	 */
	public OIMLookupUtilities getLookupUtils() {
		return new OIMLookupUtilities(logger, lookupOp, database);
	}
        
        /**
	 * Gets the lookup utilities.
	 * 
	 * @return The lookup utilities.
	 */
	public static OIMLookupUtilities getLookupUtils(Logger ClassLogger, tcLookupOperationsIntf LookupOp, tcDataProvider Database) {
		return new OIMLookupUtilities(ClassLogger, LookupOp, Database);
	}
	
	/**
	 * Gets the standard utilities.
	 * 
	 * @return The standard utilities.
	 */
	public OIMStandardUtilities getStandardUtils() {
		return new OIMStandardUtilities(logger, propertyOp, helpOp);
	}
	
	/**
	 * Gets the request utilities.
	 * 
	 * @return The request utilities.
	 */
	public OIMRequestUtilities getRequestUtils() {
		return new OIMRequestUtilities(logger, objectOp, requestOp, formInstOp, userOp, database);
	}
	
	/**
	 * Gets the resource object utilities.
	 * 
	 * @return The resource object utilities.
	 */
	public OIMResourceObjectUtilities getResObjectUtils() {
		return new OIMResourceObjectUtilities(logger, objectOp, userOp, database);
	}
	
	/**
	 * Gets the organization utilities.
	 * 
	 * @return The organization utilities.
	 */
	public OIMOrgUtilities getOrgUtils() {
		return new OIMOrgUtilities(logger, orgOp, objectOp, database);
	}
	
	/**
	 * Gets the user utilities.
	 * 
	 * @return The user utilities.
	 */
	public OIMUserUtilities getUserUtils() {
		return new OIMUserUtilities(logger, userOp, passwordOp, propertyOp, reconOp, database);
	}
}